Passed
Pull Request — master (#112)
by Mathieu
02:18
created

DateUtilsAdapter.getWorkedFreeDays   A

Complexity

Conditions 1

Size

Total Lines 20
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 18
dl 0
loc 20
c 0
b 0
f 0
rs 9.5
cc 1
1
import {Injectable} from '@nestjs/common';
2
import {
3
  format as fnsFormat,
4
  isWeekend as fnsIsWeekend,
5
  getDaysInMonth as fnsGetDaysInMonth,
6
  eachDayOfInterval,
7
  addDays
8
} from 'date-fns';
9
import {IDateUtils} from 'src/Application/IDateUtils';
10
11
@Injectable()
12
export class DateUtilsAdapter implements IDateUtils {
13
  constructor(private readonly date: Date = new Date()) {}
14
15
  public format(date: Date, format: string): string {
16
    return fnsFormat(date, format);
17
  }
18
19
  public getDaysInMonth(date: Date): number {
20
    return fnsGetDaysInMonth(date);
21
  }
22
23
  public isWeekend(date: Date): boolean {
24
    return fnsIsWeekend(date);
25
  }
26
27
  public getCurrentDate(): Date {
28
    return this.date;
29
  }
30
31
  public getCurrentDateToISOString(): string {
32
    return this.date.toISOString();
33
  }
34
35
  public getWorkedDaysDuringAPeriod(start: Date, end: Date): Date[] {
36
    const dates: Date[] = [];
37
38
    for (const day of eachDayOfInterval({start, end})) {
39
      if (
40
        this.isWeekend(day) ||
41
        this.getWorkedFreeDays(day.getFullYear()).filter(
42
          d => d.toISOString() === day.toISOString()
43
        ).length > 0
44
      ) {
45
        continue;
46
      }
47
48
      dates.push(day);
49
    }
50
51
    return dates;
52
  }
53
54
  public getWorkedFreeDays(year: number): Date[] {
55
    const fixedDays: Date[] = [
56
      new Date(`${year}-01-01`), // New Year's Day
57
      new Date(`${year}-05-01`), // Labour Day
58
      new Date(`${year}-05-08`), // Victory in 1945
59
      new Date(`${year}-07-14`), // National Day
60
      new Date(`${year}-08-15`), // Assumption
61
      new Date(`${year}-11-01`), // All Saints' Day
62
      new Date(`${year}-11-11`), // The Armistice
63
      new Date(`${year}-12-25`) // Christmas
64
    ];
65
66
    const easterDate = this.getEasterDate(year);
67
    const easterDays: Date[] = [
68
      addDays(easterDate, 1), // Easter Monday
69
      addDays(easterDate, 39) // Ascension
70
    ];
71
72
    return [...fixedDays, ...easterDays];
73
  }
74
75
  public getEasterDate(year: number): Date {
76
    const a = year % 19;
77
    const b = Math.floor(year / 100);
78
    const c = year % 100;
79
    const d = Math.floor(b / 4);
80
    const e = b % 4;
81
    const f = Math.floor((b + 8) / 25);
82
    const g = Math.floor((b - f + 1) / 3);
83
    const h = (19 * a + b - d - g + 15) % 30;
84
    const i = Math.floor(c / 4);
85
    const k = c % 4;
86
    const l = (32 + 2 * e + 2 * i - h - k) % 7;
87
    const m = Math.floor((a + 11 * h + 22 * l) / 451);
88
    const n0 = h + l + 7 * m + 114;
89
    const n = Math.floor(n0 / 31) - 1;
90
    const p = (n0 % 31) + 1;
91
92
    return new Date(year, n, p);
93
  }
94
}
95